package com.xmg.p2p.base.service.impl;

import com.xmg.p2p.base.domain.MailVerify;
import com.xmg.p2p.base.domain.Userinfo;
import com.xmg.p2p.base.mapper.MailVerifyMapper;
import com.xmg.p2p.base.mapper.UserinfoMapper;
import com.xmg.p2p.base.service.IUserinfoService;
import com.xmg.p2p.base.service.IVerifyCodeService;
import com.xmg.p2p.base.util.BitStatesUtils;
import com.xmg.p2p.base.util.DateUtil;
import com.xmg.p2p.base.util.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * lcd  2020/5/8
 * Description:处理乐观锁问题先写出来,其他地方必须调用service不能调用dao
 */
@Service
public class UserinfoServiceImpl implements IUserinfoService {
    @Autowired
    private IVerifyCodeService verifyCodeService;
    @Autowired
    private UserinfoMapper userinfoMapper;
    @Autowired
    private MailVerifyMapper mailVerifyMapper;
    @Value("${email.hosturl}")
    private String hosturl;

    @Override
    public void update(Userinfo userinfo) {
        int i = userinfoMapper.updateByPrimaryKey(userinfo);
        if (i == 0) {
            throw new RuntimeException("乐观锁错误 ,Userinfo:" + userinfo.getId());
        }
    }

    @Override
    public void add(Userinfo userinfo) {
        userinfoMapper.insert(userinfo);
    }

    @Override
    public Userinfo findById(Long id) {
        return userinfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public void bindPhone(String phoneNumber, String verifyCode) {
        //判断用户是否已经绑定了手机,安全考虑
        Userinfo user = findById(UserContext.getLogininfo().getId());
        if (user.getIsBindPhone()) {
            throw new RuntimeException("用户已经绑定手机了");
        }
        //验证逻辑
        boolean b = verifyCodeService.verify(phoneNumber, verifyCode);
        if (b) {
            //这里比较巧妙,类似于DDD领域模型
            user.setPhoneNumber(phoneNumber);
            user.addStatue(BitStatesUtils.OP_BIND_PHONE);
            //这里要用到乐观锁,所以不能用mapper要用service的update
            update(user);
        } else {
            throw new RuntimeException("绑定手机失败");
        }

    }

    @Override
    public void sendVerifyCode(String email) {
        //检查当前用户是否已经绑定邮箱
        Userinfo user = findById(UserContext.getLogininfo().getId());
        if (user.getIsBindEmail()) {
            throw new RuntimeException("用户已经绑定邮箱");
        }
        try {
            String uuid = UUID.randomUUID().toString();
            //发送邮件
            System.out.println("点击<a href='" + hosturl + "/bindEmail.do?key=" + uuid + "'" + ">这里</a>");
            //构建MailVerify
            MailVerify mailVerify = new MailVerify(null, user.getId(), new Date(), uuid, email);
            //如果成功的话,记录到数据库
            mailVerifyMapper.insert(mailVerify);
        } catch (Exception e) {
            throw new RuntimeException("发送邮箱失败");
        }

    }

    @Override
    public void bindEmail(String key) {
        MailVerify mailVerify = mailVerifyMapper.selectByUUID(key);
        if (mailVerify != null && DateUtil.secondsBetween(mailVerify.getSendDate(), new Date()) < 5 * 24 * 3600) {
            //真正绑定邮箱
            Userinfo user = findById(mailVerify.getUserinfoId());
            user.setEmail(mailVerify.getEmail());
            user.addStatue(BitStatesUtils.OP_BIND_EMAIL);
            update(user);
            //删掉那个记录
            mailVerifyMapper.delete(mailVerify.getId());
        }else {
            throw new RuntimeException("邮件校验失败,请重新绑定");
        }
    }

    @Override
    public void updateBasicInfo(Userinfo userinfo) {
        Userinfo oldUser = findById(UserContext.getLogininfo().getId());
        oldUser.setEducationBackground(userinfo.getEducationBackground());
        oldUser.setHouseCondition(userinfo.getHouseCondition());
        oldUser.setIncomeGrade(userinfo.getIncomeGrade());
        oldUser.setKidCount(userinfo.getKidCount());
        oldUser.setMarriage(userinfo.getMarriage());
        //虽然BitStatesUtils.addState 里面会判断是否有这个值,如果有了 就不变,没有了才去添加,但是这样写的话可读性更强一些
        if(!oldUser.getIsBasicInfo()){
            oldUser.addStatue(BitStatesUtils.OP_BASIC_INFO);//到这里说明用户进行了基本信息的填写,状态就要改了
        }
        update(oldUser);
    }

    @Override
    public Userinfo getCurrent() {
        return findById(UserContext.getLogininfo().getId());
    }

    @Override
    public List<Map<String, Object>> autoComplate(String keyword) {
        return userinfoMapper.autocomplate(keyword);
    }
}
